package com.sevennotes.classtable.ui.pages

import android.content.Context
import android.net.Uri
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.AlertDialog
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.modifier.modifierLocalConsumer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.godaddy.android.colorpicker.ClassicColorPicker
import com.sevennotes.classtable.config.Settings
import com.sevennotes.classtable.ui.pages.components.ConfirmAndCancelButtons
import com.sevennotes.classtable.ui.pages.components.ItemCell
import com.sevennotes.classtable.ui.pages.components.NumberInput
import com.sevennotes.classtable.ui.pages.components.SimpleComfirmDialog
import com.sevennotes.classtable.ui.pages.components.SimpleMsgDialog
import com.sevennotes.classtable.ui.pages.main_screen.SettingsState

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun SettingsPage(
  settingsState: SettingsState,
  themeColor: Color,
  onColorChange: (Color) -> Unit,
  onBackup: (Uri, Context) -> Unit,
  onRecovery: (Uri, Context) -> Unit,
  onNetBackup: ((String) -> Unit) -> Unit,
  onNetRecovery: (String, (String) -> Unit) -> Unit,
  refreshBackupFileList: (onError: (String) -> Unit) -> Unit,
  deleteBackupFile: (fileName: String, finish: (String) -> Unit) -> Unit
) {
  var colorPickerVis by remember { mutableStateOf(false) }
  val context = LocalContext.current
  val keyboard = LocalSoftwareKeyboardController.current
  var messageshow by remember { mutableStateOf(false) }
  var netRecoverConfirmShow by remember { mutableStateOf(false) }
  var localRecoverConfirmShow by remember { mutableStateOf(false) }
  var fileListShow by remember { mutableStateOf(false) }
  var deleteBackupFileShow by remember { mutableStateOf(false) }
  var recoveryUri by remember { mutableStateOf<Uri?>(null) }
  var netRecoveryFileName by remember { mutableStateOf<String?>(null) }
  var message by remember { mutableStateOf("") }
  val launcher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.GetContent(),
    onResult = {
      if (it != null) {
        recoveryUri = it
        localRecoverConfirmShow = true
      }
    }
  )
  val slauncher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.CreateDocument(),
    onResult = {
      if (it != null) {
        onBackup(it, context)
      }
    }
  )

  var netDeleteFileName by remember { mutableStateOf<String?>(null) }
  var netDeleteConfirmShow by remember { mutableStateOf(false) }

  if (deleteBackupFileShow) {
    LaunchedEffect(Unit) {
      refreshBackupFileList() {
        Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
      }
    }
    FileNameListDialog(
      title = "选择需要删除的文件：",
      backupFileList = settingsState.backupFileList,
      autoBackupFileList = settingsState.autoBackupFileList,
      onConfirmClick = { fileName ->
        netDeleteFileName = fileName
        netDeleteConfirmShow = true
      },
      onCancelClick = { deleteBackupFileShow = false }
    )
  }

  if (netDeleteConfirmShow) {
    SimpleComfirmDialog(
      text = "删除数据之后不能恢复！确定要删除吗？",
      onConfirmClick = {
        netDeleteConfirmShow = false
        netDeleteFileName?.let {filePath ->
          deleteBackupFile(filePath) {
            message = it
            messageshow = true
            netDeleteFileName = null
            refreshBackupFileList() {
              Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
            }
          }
        }
      },
      onCancelClick = {
        netDeleteFileName = null
        netDeleteConfirmShow = false
      }
    )
  }

  if (fileListShow) {
    LaunchedEffect(Unit) {
      refreshBackupFileList() {
        Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
      }
    }
    FileNameListDialog(
      title = "选择需要恢复的文件：",
      backupFileList = settingsState.backupFileList,
      autoBackupFileList = settingsState.autoBackupFileList,
      onConfirmClick = { fileName ->
        netRecoveryFileName = fileName
        netRecoverConfirmShow = true
      },
      onCancelClick = { fileListShow = false }
    )
  }

  if (messageshow) {
    SimpleMsgDialog(text = message) {
      messageshow = false
    }
  }

  if (localRecoverConfirmShow) {
    SimpleComfirmDialog(
      text = "确定要恢复吗？这将覆盖现有的数据！",
      onConfirmClick = {
        recoveryUri?.let { onRecovery(it, context) }
        localRecoverConfirmShow = false
        recoveryUri = null
      },
      onCancelClick = {
        recoveryUri = null
        localRecoverConfirmShow = false
      }
    )
  }

  if (netRecoverConfirmShow) {
    SimpleComfirmDialog(
      text = "确定要恢复吗？这将覆盖现有的数据！",
      onConfirmClick = {
        netRecoveryFileName?.let {
          onNetRecovery(it) { msg ->
            message = msg
            messageshow = true
            fileListShow = false
          }
        }
        netRecoverConfirmShow = false
        netRecoveryFileName = null
      },
      onCancelClick = {
        netRecoveryFileName = null
        netRecoverConfirmShow = false
      }
    )
  }

  if (settingsState.busy) {
    AlertDialog(
      onDismissRequest = {},
      buttons = { Spacer(modifier = Modifier.height(30.dp)) },
      title = { Text("请求网络中...") }
    )
  }
  //主列表
  Column(
    modifier = Modifier
      .fillMaxSize()
      .verticalScroll(rememberScrollState())
  ) {
    Spacer(modifier = Modifier.height(10.dp))
    var serverSetting by remember { mutableStateOf(false) }
    SettingsCell(title = "webDav服务器设置", isOpen = serverSetting) {
      keyboard?.hide()
      serverSetting = !serverSetting
    }
    //webdav 服务设置列表
    AnimatedVisibility(serverSetting) {
      Column {
        ItemCell {
          OutlinedTextField(
            modifier = Modifier.fillMaxWidth(),
            value = Settings.webDavUrl,
            onValueChange = { Settings.webDavUrl = it },
            label = { Text("webCav数据服务器地址") }
          )
        }
        ItemCell {
          OutlinedTextField(
            modifier = Modifier.fillMaxWidth(),
            value = Settings.webDavUsername,
            onValueChange = { Settings.webDavUsername = it },
            label = { Text("webCav账号") }
          )
        }
        ItemCell {
          OutlinedTextField(
            modifier = Modifier.fillMaxWidth(),
            value = Settings.webDavPassword,
            onValueChange = { Settings.webDavPassword = it },
            label = { Text("webCav密码") }
          )
        }
        ItemCell {
          OutlinedTextField(
            modifier = Modifier.fillMaxWidth(),
            value = Settings.dirName,
            onValueChange = { Settings.dirName = it },
            label = { Text("存储文件夹") }
          )
        }
      }
    }
    var backupSettings by remember { mutableStateOf(false) }
    SettingsCell(title = "数据备份还原", isOpen = backupSettings) {
      keyboard?.hide()
      backupSettings = !backupSettings
    }
    AnimatedVisibility(visible = backupSettings) {
      Column(modifier = Modifier.padding(start = 20.dp)) {
        ButtonSettingsCell(title = "网络数据备份") {
          onNetBackup {
            messageshow = true
            message = it
          }
        }
        ButtonSettingsCell(title = "网络数据还原") {
          fileListShow = true
        }
        ButtonSettingsCell(title = "本地数据备份") { slauncher.launch("backup.json") }
        ButtonSettingsCell(title = "本地数据还原") { launcher.launch("*/*") }
        ButtonSettingsCell(title = "删除网络备份文件") { deleteBackupFileShow = true }
      }
    }

    var autoBackupSettings by remember { mutableStateOf(false) }
    SettingsCell(title = "自动备份配置", isOpen = autoBackupSettings) {
      keyboard?.hide()
      autoBackupSettings = !autoBackupSettings
    }
    AnimatedVisibility(visible = autoBackupSettings) {
      Column(modifier = Modifier.padding(start = 20.dp)) {
        CheckBoxItemCell(title = "是否开启自动备份", checked = Settings.autoSaveEnable) {
          Settings.autoSaveEnable = !Settings.autoSaveEnable
        }
        CheckBoxItemCell(
          title = "移动网络是否允许自动备份",
          checked = Settings.shouldAutoSaveInMobileNetwork
        ) {
          Settings.shouldAutoSaveInMobileNetwork = !Settings.shouldAutoSaveInMobileNetwork
        }
        InputBoxItemCell(
          title = "自动备份保留文件数",
          number = Settings.maxAutoSaveFileNumber,
          onNumChanged = { Settings.maxAutoSaveFileNumber = it }
        )
        InputBoxItemCell(
          title = "自动备份间隔天数",
          number = Settings.autoSaveIntervalDays,
          onNumChanged = { Settings.autoSaveIntervalDays = it }
        )
      }
    }

    ItemCell {
      var menu by remember { mutableStateOf(false) }
      Text(text = "每日开始时间", modifier = Modifier.weight(1f), fontSize = 16.sp)
      OutlinedButton(onClick = { menu = !menu }) {
        SimpleMenu(list = listOf(6, 7, 8, 9), onClick = {Settings.beginHour = it}, visible = menu) {
          menu = false
        }
        Text(text = "${Settings.beginHour} 点")
      }
    }
    ItemCell {
      var menu by remember { mutableStateOf(false) }
      Text(text = "每日结束时间", modifier = Modifier.weight(1f), fontSize = 16.sp)
      OutlinedButton(onClick = { menu = !menu }) {
        SimpleMenu(list = listOf(19, 20, 21, 22, 23), onClick = {Settings.endHour = it}, visible = menu) {
          menu = false
        }
        Text(text = "${Settings.endHour} 点")
      }
    }
    SettingsCell(title = "主题颜色", isOpen = colorPickerVis) {
      keyboard?.hide()
      colorPickerVis = !colorPickerVis
    }
    if (colorPickerVis) {
      Spacer(modifier = Modifier.height(10.dp))
      ClassicColorPicker(
        modifier = Modifier
          .height(200.dp)
          .padding(horizontal = 10.dp),
        showAlphaBar = false,
        color = themeColor,
      ) {
        onColorChange(it.toColor())
      }
      Spacer(modifier = Modifier.height(20.dp))
    }
  }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FileNameListDialog(
  title: String,
  backupFileList: List<String> = emptyList(),
  autoBackupFileList: List<String> = emptyList(),
  onConfirmClick: (fileName: String) -> Unit,
  onCancelClick: () -> Unit,
) {
  var showAutoList by remember { mutableStateOf(false) }
  var selected by remember { mutableStateOf(0) }
  var currentFileName by remember(backupFileList) {
    mutableStateOf(
      if (backupFileList.isNotEmpty()) backupFileList[0] else ""
    )
  }
  AlertDialog(
    title = { Text(title) },
    text = {
      Column {
        TabRow(selectedTabIndex = selected) {
          Tab(selected = !showAutoList, onClick = {
            selected = 0
            showAutoList = false
          }) {
            Text(text = "手动备份的文件")
          }
          Tab(selected = showAutoList, onClick = {
            selected = 1
            showAutoList = true
          }) {
            Text(text = "自动备份的文件")
          }
        }
        LazyColumn(
          modifier = Modifier.height(350.dp)
        ) {
          items(if (showAutoList) autoBackupFileList else backupFileList) {
            Row(
              modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 5.dp),
              horizontalArrangement = Arrangement.Start,
              verticalAlignment = Alignment.CenterVertically
            ) {
              RadioButton(selected = it == currentFileName, onClick = { currentFileName = it })
              Text(text = it)
            }
          }
        }
      }
    },
    onDismissRequest = onCancelClick,
    buttons = {
      ConfirmAndCancelButtons(
        onConfirmClick = {
          onConfirmClick(
            if (showAutoList)
              "${Settings.autoSaveDir}/$currentFileName"
            else
              "${Settings.dirName}/$currentFileName"
          )
        },
        onCancelClick = onCancelClick
      )
    }
  )
}

@Preview(showBackground = true)
@Composable
fun FileNameListDialogPreview() {
  val list = mutableListOf<String>()
  for (i in 0..100) {
    list.add("auto$i")
  }
  FileNameListDialog(
    title = "选择需要恢复的文件：",
    autoBackupFileList = list,
    onConfirmClick = {},
    onCancelClick = {}
  )
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun InputBoxItemCell(
  title: String,
  number: Int,
  onNumChanged: (Int) -> Unit,
) {
  val keyboard = LocalSoftwareKeyboardController.current
  ItemCell {
    Text(text = title, fontSize = 16.sp)
    Spacer(modifier = Modifier.weight(1f))
    NumberInput(
      modifier = Modifier.padding(vertical = 5.dp),
      initialNumber = number,
      onNumberChanged = onNumChanged,
      onMinusClick = { onNumChanged(number - 1) },
      onPlusClick = { onNumChanged(number + 1) }
    )
  }
}

@Composable
fun SettingsCell(
  title: String,
  isOpen: Boolean = false,
  onClick: () -> Unit
) {
  ItemCell(
    modifier = Modifier.clickable { onClick() },
  ) {
    Text(text = title, modifier = Modifier.weight(1f), fontSize = 16.sp)
    if (isOpen) {
      Icon(imageVector = Icons.Filled.KeyboardArrowDown, contentDescription = null)
    } else {
      Icon(imageVector = Icons.Filled.KeyboardArrowUp, contentDescription = null)
    }
  }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CheckBoxItemCell(
  title: String,
  checked: Boolean,
  onClick: () -> Unit = {},
) {
  ItemCell(
    modifier = Modifier.clickable { onClick() }
  ) {
    Text(text = title, modifier = Modifier.weight(1f), fontSize = 16.sp)
    Checkbox(checked = checked, onCheckedChange = { onClick() })
  }
}

@Composable
fun ButtonSettingsCell(
  title: String,
  onClick: () -> Unit
) {
  ItemCell(
    modifier = Modifier.clickable { onClick() },
  ) {
    Text(text = title, modifier = Modifier.weight(1f), fontSize = 16.sp)
    Icon(imageVector = Icons.Filled.KeyboardArrowRight, contentDescription = null)
  }
}

@Composable
fun SimpleMenu(
  list: List<Int>,
  onClick: (Int) -> Unit,
  visible: Boolean,
  onDismiss: () -> Unit
) {
  DropdownMenu(expanded = visible, onDismissRequest = onDismiss) {
    list.forEach {
      DropdownMenuItem(text = { Text("$it") }, onClick = {
        onClick(it)
        onDismiss()
      })
    }
  }
}